import { Tree } from 'antd';
import { useState } from 'react';

const x = 3;
const y = 2;
const z = 1;

const defaultData = [];

const generateData = (_level, _preKey, _tns) => {
  const preKey = _preKey || '0';
  const tns = _tns || defaultData;
  const children = [];
  for (let i = 0; i < x; i++) {
    const key = `${preKey}-${i}`;
    tns.push({
      title: key,
      key,
    });
    if (i < y) {
      children.push(key);
    }
  }
  if (_level < 0) {
    return tns;
  }
  const level = _level - 1;
  children.forEach((key, index) => {
    tns[index].children = [];
    return generateData(level, key, tns[index].children);
  });
};

generateData(z);

const App = () => {
  const [gData, setGData] = useState(defaultData);
  const [expandedKeys] = useState(['0-0', '0-0-0', '0-0-0-0']);

  // noinspection JSUnusedLocalSymbols
  const onDragEnter = (info) => {
    // expandedKeys 需要受控时设置
    // setExpandedKeys(info.expandedKeys)
  };

  const onDrop = (info) => {
    const dropKey = info.node.key;
    const dragKey = info.dragNode.key;
    const dropPos = info.node.pos.split('-');
    const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);

    const dropToRootLevel = (info) => {
      if (!isRootNode(info.node.pos))
        return false;
      return !dropInto(info);
    }

    const isRootNode = (pos) => {
      return pos.split('-').length === 2;
    }

    const dropInto = (info) => {
      if (!info.dropToGap)
        return true;
      if (dropPosition === -1)
        return false;
      if (!hasChildren(info.node))
        return false;
      return info.node.expanded;
    }

    const hasChildren = (node) => {
      let children = node.children || [];
      return children.length > 0;
    }

    if (dropToRootLevel(info)) {
      alert('不能新增根结点！');
      return;
    }

    const loop = (data, key, callback, parent) => {
      for (let i = 0; i < data.length; i++) {
        if (data[i].key === key) {
          return callback(data[i], i, data, parent);
        }
        if (data[i].children) {
          loop(data[i].children, key, callback, data[i]);
        }
      }
    };

    const data = [...gData];

    // Find dragObject
    let dragObj;
    loop(data, dragKey, (item, index, arr) => {
      arr.splice(index, 1);
      dragObj = item;
    });

    let parentNode;

    if (!info.dropToGap) {
      // Drop on the content
      loop(data, dropKey, (item) => {
        item.children = item.children || [];
        // where to insert 示例添加到头部，可以是随意位置
        item.children.unshift(dragObj);
        parentNode = item;
      });
    } else if (
        hasChildren(info.node) &&
        // Has children
        info.node.expanded &&
        // Is expanded
        dropPosition === 1 // On the bottom gap
    ) {
      loop(data, dropKey, (item) => {
        item.children = item.children || [];
        // where to insert 示例添加到头部，可以是随意位置
        item.children.unshift(dragObj);
        // in previous version, we use item.children.push(dragObj) to insert the
        // item to the tail of the children
        parentNode = item;
      });
    } else {
      let ar = [];
      let i;
      loop(data, dropKey, (_item, index, arr, parent) => {
        ar = arr;
        i = index;
        parentNode = parent;
      });
      if (dropPosition === -1) {
        ar.splice(i, 0, dragObj);
      } else {
        ar.splice(i + 1, 0, dragObj);
      }
    }

    setGData(data);

    const showChildren = (node) => {
      console.log(node.title);
      node.children.forEach(child => {
        console.log(`  ${child.title}`);
      })
    }

    showChildren(parentNode);
  };

  return (
      <Tree
          className='draggable-tree'
          defaultExpandedKeys={expandedKeys}
          draggable
          blockNode
          onDragEnter={onDragEnter}
          onDrop={onDrop}
          treeData={gData}
      />
  );
};

export default App;